home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Dialectic 1.2 / source / Dialectic ƒ / Shell ƒ / prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  11.8 KB  |  432 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        prefs.c
  4.  
  5. Purpose:    This module handles creating/opening/closing/updating
  6.             the preference file, and copying the preference file
  7.             data into application globals (and back).
  8.  
  9. \**********************************************************************/
  10.  
  11. #include "prefs.h"
  12. #include "dialogs.h"
  13. #include "environment.h"
  14. #include "util.h"
  15. #include "program globals.h"
  16. #include "Folders.h"
  17.  
  18. #define        PREFS_FILE_NAME            "\pDialectic prefs"
  19. #define        PREFS_TYPE                'PREF'
  20. // CREATOR is #defined in "program globals.h"
  21. #define        PREFS_HEADER_VERSION    2
  22.  
  23. Str255            gMyName;
  24. Str255            gMyOrg;
  25.  
  26. typedef struct
  27. {
  28.     char            regname[40];
  29.     char            regorg[40];
  30.     unsigned char    showsave;
  31.     unsigned char    addsuffix;
  32.     unsigned char    showprogress;
  33.     unsigned char    dialect;
  34.     unsigned char    useRTF;
  35.     unsigned char    unused;
  36.     long            fileID;
  37. } PrefStruct;
  38.  
  39. enum        /* possible error codes */
  40. {
  41.     prefs_allsWell=0,                /* no error */
  42.     prefs_diskReadErr,                /* error reading prefs file */
  43.     prefs_diskWriteErr,                /* error writing prefs file */
  44.     prefs_cantOpenPrefsErr,            /* error trying to open prefs file */
  45.     prefs_cantCreatePrefsErr,        /* error trying to create new prefs file */
  46.     prefs_noMorePrefsErr,            /* no more prefs found in prefs file */
  47.     prefs_versionNotSupportedErr,    /* prefs file created by later version of program */
  48.     prefs_virginErr,                /* prefs file didn't exist -- first time running */
  49.     prefs_IDNotMatchErr                /* file ID in current prefs doesn't match program's ID */
  50. };
  51.  
  52. /* internal globals for use in prefs.c only */
  53. static long            gFileID;
  54. static Boolean        gCanSavePrefs;
  55. static PrefStruct    thePrefs;
  56. static long            gPrefsFilePos;
  57.  
  58. /*-----------------------------------------------------------------------------------*/
  59. /* internal stuff for prefs.c                                                        */
  60.  
  61. int OpenPrefsFile(int *prefsFileID);
  62. int SetupNewPrefsFile(int prefsFileID);
  63. void ClosePrefsFile(int prefsFileID);
  64. int GetNextPrefs(int prefsFileID);
  65. int SavePrefs(int prefsFileID);
  66. int CheckVersion(int prefsFileID);
  67. int GetFileID(void);
  68. int CheckFileID(void);
  69. int Virgin(int prefsFileID);
  70. void DefaultPrefs(void);
  71. void CopyGlobalsToPrefs(void);
  72. void CopyPrefsToGlobals(void);
  73. void GetRegistration(void);
  74.  
  75. void SaveThePrefs(void)
  76. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  77. {
  78.     int            prefsFileID;
  79.     
  80.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  81.     {
  82.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  83.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  84.         SavePrefs(prefsFileID);            /* save prefs to disk */
  85.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  86.     }
  87. }
  88.  
  89. int PreferencesInit(void)
  90. {
  91.     int                prefsFileID;
  92.     int                err;
  93.     
  94.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  95.     err=GetFileID();        /* get application file ID */
  96.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  97.         return err;
  98.     
  99.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  100.     if (err!=prefs_allsWell)
  101.     {
  102.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  103.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  104.         return err;
  105.     }
  106.     
  107.     err=CheckVersion(prefsFileID);        /* check prefs version */
  108.     if (err!=prefs_allsWell)
  109.     {
  110.         ClosePrefsFile(prefsFileID);
  111.         return err;
  112.     }
  113.     
  114.     GetFPos(prefsFileID, &gPrefsFilePos);
  115.     gPrefsFilePos-=sizeof(thePrefs);
  116.     do
  117.     {
  118.         gPrefsFilePos+=sizeof(thePrefs);
  119.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  120.         if (err==prefs_noMorePrefsErr)        /* or not */
  121.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  122.         
  123.         if (err!=prefs_allsWell)            /* any other error, just abort */
  124.         {
  125.             ClosePrefsFile(prefsFileID);
  126.             return err;
  127.         }
  128.         
  129.         err=CheckFileID();                    /* check file ID of current prefs struct */
  130.     }
  131.     while (err==prefs_IDNotMatchErr);
  132.     
  133.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  134.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  135.     
  136.     return prefs_allsWell;                    /* piece o' cake */
  137. }
  138.  
  139. void PrefsError(int err)
  140. {
  141.     Str255            tempStr;
  142.     
  143.     switch (err)
  144.     {
  145.         case prefs_diskReadErr:
  146.         case prefs_diskWriteErr:
  147.         case prefs_cantCreatePrefsErr:
  148.         case prefs_cantOpenPrefsErr:
  149.         case prefs_versionNotSupportedErr:
  150.             DefaultPrefs();                    /* use default prefs if error */
  151.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  152.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  153.             ParamText(tempStr, "\p", "\p", "\p");
  154.             PositionDialog('ALRT', largeAlert);
  155.             StopAlert(largeAlert, 0L);        /* display error alert */
  156.             break;
  157.         default:
  158.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  159.             break;
  160.     }
  161. }
  162.  
  163. int OpenPrefsFile(int *prefsFileID)
  164. {
  165.     int                thisFile;
  166.     OSErr            isHuman;
  167.     int                vRefNum;
  168.     long            dirID;
  169.     FSSpec            prefsFile;
  170.     FInfo            prefsInfo;
  171.     Boolean            newPrefs;
  172.     unsigned char    *name=PREFS_FILE_NAME;
  173.     
  174.     newPrefs=FALSE;
  175.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  176.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  177.     
  178.     if (isHuman!=noErr)        /* screwed up already?!? */
  179.         return prefs_cantOpenPrefsErr;
  180.     if (gHasFSSpecs)
  181.     {
  182.         isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  183.         if (isHuman!=noErr)
  184.         {
  185.             if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  186.             {
  187.                 isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  188.                 if (isHuman!=noErr)                                        /* or not */
  189.                     return prefs_cantCreatePrefsErr;
  190.                 newPrefs=TRUE;        /* signal that prefs file is new */
  191.             }
  192.             else return prefs_cantOpenPrefsErr;
  193.         }
  194.         isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  195.         *prefsFileID=thisFile;        /* store file reference number */
  196.         if (isHuman!=noErr)
  197.             return prefs_cantOpenPrefsErr;
  198.     }
  199.     else
  200.     {
  201.         /* try to open prefs file */
  202.         isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  203.         *prefsFileID=thisFile;
  204.         if (isHuman!=noErr)
  205.         {
  206.             if (isHuman==fnfErr)    /* prefs file does not exist */
  207.             {
  208.                 /* ...so create it */
  209.                 if (HCreate(vRefNum, dirID, name, CREATOR, PREFS_TYPE)!=noErr)
  210.                     return prefs_cantCreatePrefsErr;
  211.                 prefsInfo.fdType=PREFS_TYPE;
  212.                 prefsInfo.fdCreator=CREATOR;
  213.                 prefsInfo.fdFlags=0;
  214.                 prefsInfo.fdLocation.h=prefsInfo.fdLocation.v=0;
  215.                 prefsInfo.fdFldr=0;
  216.                 
  217.                 /* set file info of newly created prefs file */
  218.                 if (HSetFInfo(vRefNum, dirID, name, &prefsInfo)!=noErr)
  219.                     return prefs_cantCreatePrefsErr;
  220.                 
  221.                 /* NOW open the prefs file */
  222.                 isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  223.                 *prefsFileID=thisFile;        /* store file reference number */
  224.                 if (isHuman!=noErr)
  225.                     return prefs_cantOpenPrefsErr;
  226.                 newPrefs=TRUE;                /* signal that prefs file is new */
  227.             }
  228.             else return prefs_cantOpenPrefsErr;
  229.         }
  230.     }
  231.     if (newPrefs)
  232.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  233.     
  234.     return prefs_allsWell;
  235. }
  236.  
  237. int SetupNewPrefsFile(int prefsFileID)
  238. /* this writes the prefs version number to the newly created prefs file, so we can
  239.    tell if the prefs file was created by a later version of the program and is
  240.    therefore in a format that we don't support -- forward compatability!  what
  241.    a concept! */
  242. {
  243.     long            count;
  244.     int                temp;
  245.     
  246.     gPrefsFilePos=2L;
  247.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  248.         return prefs_diskWriteErr;
  249.     
  250.     SetFPos(prefsFileID, 1, 0L);
  251.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  252.     count=2L;
  253.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  254.         return prefs_diskWriteErr;        
  255.     
  256.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  257. }
  258.  
  259. void ClosePrefsFile(int prefsFileID)
  260. {
  261.     FSClose(prefsFileID);                /* close file on disk */
  262.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  263. }
  264.  
  265. int GetNextPrefs(int prefsFileID)
  266. {
  267.     OSErr        isHuman;
  268.     long        count;
  269.     
  270.     count=sizeof(thePrefs);
  271.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  272.     if (isHuman==eofErr)    /* no more left */
  273.         return prefs_noMorePrefsErr;
  274.     if (isHuman!=noErr)        /* some other error */
  275.         return prefs_diskReadErr;
  276.     
  277.     return prefs_allsWell;
  278. }
  279.  
  280. int SavePrefs(int prefsFileID)
  281. {
  282.     long        oldEOF;
  283.     long        count;
  284.     
  285.     GetEOF(prefsFileID, &oldEOF);
  286.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  287.     {
  288.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  289.             return prefs_diskWriteErr;
  290.     }
  291.     
  292.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  293.     count=sizeof(thePrefs);
  294.     /* write prefs struct and return appropriate error code */
  295.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  296.         prefs_diskWriteErr : prefs_allsWell;
  297. }
  298.  
  299. int CheckVersion(int prefsFileID)
  300. {
  301.     OSErr        isHuman;
  302.     long        count;
  303.     int            temp;
  304.     
  305.     count=2L;
  306.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  307.     if (isHuman!=noErr)
  308.         return prefs_diskReadErr;
  309.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  310.         return prefs_versionNotSupportedErr;
  311.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  312.         return SetupNewPrefsFile(prefsFileID);
  313.     
  314.     return prefs_allsWell;
  315. }
  316.  
  317. int GetFileID(void)
  318. {
  319.     ParamBlockRec    pb;
  320.     
  321.     pb.fileParam.ioCompletion=0L;
  322.     pb.fileParam.ioNamePtr=CurApName;
  323.     pb.fileParam.ioVRefNum=0;
  324.     pb.fileParam.ioFVersNum=0;
  325.     pb.fileParam.ioFDirIndex=0;
  326.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  327.         return prefs_diskReadErr;
  328.     
  329.     gFileID=pb.fileParam.ioFlNum;
  330. }
  331.  
  332. int CheckFileID(void)
  333. {
  334.     /* compare file ID in current prefs struct to application's file ID */
  335.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  336. }
  337.  
  338. int Virgin(int prefsFileID)
  339. {
  340.     int            err;
  341.     
  342.     DefaultPrefs();
  343.     CopyGlobalsToPrefs();
  344.     err=SavePrefs(prefsFileID);
  345.     if (err!=prefs_allsWell)
  346.         return err;
  347.     GetRegistration();
  348.     CopyGlobalsToPrefs();
  349.     err=SavePrefs(prefsFileID);
  350.     
  351.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  352. }
  353.  
  354. void DefaultPrefs(void)
  355. {
  356.     StuffHex(gMyName, "\p03426F62");    /* Bob */
  357.     gMyOrg[0]=gWhichDialect=0x00;
  358.     gUseRTF=gShowSaveDialog=gAddSuffix=gShowProgress=0xFF;
  359. }
  360.  
  361. void CopyGlobalsToPrefs(void)
  362. {
  363.     Mymemset(&thePrefs, 0, sizeof(thePrefs));
  364.     if (gMyName[0]>0x27)
  365.         gMyName[0]=0x27;
  366.     if (gMyOrg[0]>0x27)
  367.         gMyOrg[0]=0x27;
  368.     Mymemcpy(thePrefs.regname, gMyName, gMyName[0]+1);
  369.     Mymemcpy(thePrefs.regorg, gMyOrg, gMyOrg[0]+1);
  370.     thePrefs.showsave=gShowSaveDialog;
  371.     thePrefs.addsuffix=gAddSuffix;
  372.     thePrefs.showprogress=gShowProgress;
  373.     thePrefs.dialect=gWhichDialect;
  374.     thePrefs.useRTF=gUseRTF;
  375.     thePrefs.unused=0x00;
  376.     thePrefs.fileID=gFileID;
  377. }
  378.  
  379. void CopyPrefsToGlobals(void)
  380. {
  381.     Mymemcpy(gMyName, thePrefs.regname, thePrefs.regname[0]+1);
  382.     Mymemcpy(gMyOrg, thePrefs.regorg, thePrefs.regorg[0]+1);
  383.     gShowSaveDialog=thePrefs.showsave;
  384.     gAddSuffix=thePrefs.addsuffix;
  385.     gShowProgress=thePrefs.showprogress;
  386.     gWhichDialect=thePrefs.dialect;
  387.     gUseRTF=thePrefs.useRTF;
  388. }
  389.  
  390. void GetRegistration(void)
  391. {
  392.     DialogPtr        theDlog;
  393.     int                itemSelected = 0;
  394.     int                newleft;
  395.     int                newtop;
  396.     int                itemType;
  397.     Handle            item;
  398.     Rect            box;
  399.     
  400.     theDlog = GetNewDialog(personalDialog, 0L, (WindowPtr)-1L);
  401.     newleft = screenBits.bounds.left + (((screenBits.bounds.right -
  402.                 screenBits.bounds.left) - (theDlog->portRect.right -
  403.                 theDlog->portRect.left)) / 2);
  404.     newtop = screenBits.bounds.top + (((screenBits.bounds.bottom -
  405.                 screenBits.bounds.top) - (theDlog->portRect.bottom -
  406.                 theDlog->portRect.top)) / 2);
  407.     if(newtop < 15)
  408.         newtop = 15;
  409.     GetDItem(theDlog, 1, &itemType, &item, &box);
  410.     InsetRect(&box, -4, -4);
  411.     SetDItem(theDlog, 8, userItem, OutlineDefaultButton, &box);
  412.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  413.     
  414.     MoveWindow(theDlog, newleft, newtop, TRUE);
  415.     ShowWindow(theDlog);
  416.     while(itemSelected != 1)
  417.     {
  418.         ModalDialog(0L, &itemSelected);
  419.     }
  420.     GetDItem(theDlog,4,&itemType,&item,&box);
  421.     GetIText(item,&gMyName);
  422.     
  423.     GetDItem(theDlog,5,&itemType,&item,&box);
  424.     GetIText(item,&gMyOrg);
  425.  
  426.     if (gMyName[0]==0x00)
  427.         DefaultPrefs();
  428.  
  429.     HideWindow(theDlog);
  430.     DisposeDialog(theDlog);
  431. }
  432.